(in-package #:experiment)

(defclass message (state)
  ((text :initarg :text :accessor message-text)
   (font :initarg :font :accessor message-font))
  (:default-initargs
   :font (gwee:open-font "sans.ttf" 36)))

(defclass click-message (message)
  ((delay :initform 1 :initarg :delay :accessor delay)
   (onward-text :initform "Click to Continue" :initarg :onward-text :accessor onward-text)
   (allow-continue :initform nil :accessor allow-continue))
  (:documentation "Like a regular message but you must click to go forward."))

(defclass instructions (message)
  ()
  (:documentation "the same as message, but it looks different in the logs. So it's useful."))

(defclass click-instructions (click-message)
  ()
  (:documentation "Like regular instructions but you must click to go forward."))

(defmethod state-init (experiment (state message))
  (log experiment 'start :text (message-text state))
  (make-instance 'gwee:text-area
                 :x :center :y :center
                 :parent state
                 :font (message-font state)
                 :data (message-text state)))

(defmethod state-init (experiment (state click-message))
  (call-next-method)
  (setf (gwee:margin-bottom (first (gwee:view-subviews state))) 100)
  (start-timer (delay state)))

(defmethod state-dump append (experiment (state message))
  `(:text ,(message-text state)))

(defmethod state-list-actions append (experiment (state message))
  (default-list-actions state))

(defmethod state-list-objects append (experiment (state message))
  `(:text ,(message-text state)))

(define-action onward ((state message)
                       (keypress :char #\Space))
  (state-onward *experiment* state))

(defmethod state-list-objects append (experiment (state click-message))
  `(:continue-text-visible-p ,(if (allow-continue state) t nil)))

(define-action add-click-message ((state click-message)
                                  (timeout))
  (setf (allow-continue state) t)
  (make-instance 'gwee:text-area
                 :left-padding 20
                 :right-padding 20
                 :top-padding 10
                 :bottom-padding 10
                 :foreground (gwee:gray 255)
                 :background (gwee:gray 180)
                 :font (gwee:view-font (first (gwee:view-subviews state)))
                 :x :center :y (- (gwee:view-height state)
                                  100)
                 :data (onward-text state)
                 :parent state)
  (setf (gwee:view-needs-update-p state) t)
  t)

(define-state-match continue ((state click-message)
                              possiblep)
  (eq (allow-continue state) (not (not possiblep))))

(define-action onward ((state click-message)
                       (click)
                       (continue :possiblep t))
  (state-onward *experiment* state))

(defmethod gwee:mouse-press-event ((obj message) button x y)
  (state-dispatch-event *experiment* obj (make-instance 'click-event :source :state)))

(defclass end (state)
  ((message :initarg :message :initform "End Of Session" :accessor end-message)))

(defmethod state-init (experiment (state end))
  (log experiment 'start)
  (make-instance 'gwee:column-layout
                 :parent state
                 :width (gwee:view-width state) :height (gwee:view-height state)
                 :subviews (list (make-instance 'gwee:text-area :data (end-message state)))))

(defmethod state-run (experiment (state end))
  (state-onward experiment state))
